/**
解释器模式（Interpreter Pattern）

意图：给定一个语言，定义它的文法表示，并定义一个解释器，这个解释器使用该标识来解释语言中的句子。
主要解决：对于一些固定文法构建一个解释句子的解释器。
何时使用：如果一种特定类型的问题发生的频率足够高，那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器，该解释器通过解释这些句子来解决该问题。
如何解决：构建语法树，定义终结符与非终结符。
*/
main(List<String> args) {
  Expression robert = TerminalExpression("Robert");
  Expression john = TerminalExpression("John");
  Expression isMale = OrExpression(robert, john);
  print("John is male? ${isMale.interpret('john')}");

  Expression julie = TerminalExpression("Julie");
  Expression married = TerminalExpression("Married");
  Expression isMarriedWoman = AndExpression(julie, married);
  print(
      "Julie is a married women? ${isMarriedWoman.interpret('Married Julie')}");
}

//////////////////////////////////////////////////////////////////

///
/// 创建一个表达式接口
///
abstract class Expression {
  bool interpret(String context);
}

///
/// 创建实现了上述接口的实体类
///
class TerminalExpression implements Expression {
  String _data;

  TerminalExpression(this._data);

  @override
  bool interpret(String context) {
    if (context.contains(_data)) {
      return true;
    }
    return false;
  }
}

class OrExpression implements Expression {
  Expression _expr1;
  Expression _expr2;

  OrExpression(this._expr1, this._expr2);

  @override
  bool interpret(String context) {
    return _expr1.interpret(context) || _expr2.interpret(context);
  }
}

class AndExpression implements Expression {
  Expression _expr1;
  Expression _expr2;

  AndExpression(this._expr1, this._expr2);

  @override
  bool interpret(String context) {
    return _expr1.interpret(context) && _expr2.interpret(context);
  }
}
